"""
爬虫失败记录数据访问层
"""
from typing import List, Optional, Dict, Any
from datetime import datetime
from axiom_boot.database.base_mapper import BaseMapper
from axiom_boot.di import mapper
from ..models.scraper_failed_record import ScraperFailedRecord, RetryStatus


@mapper()
class ScraperFailedRecordMapper(BaseMapper[ScraperFailedRecord]):
    """爬虫失败记录Mapper"""
    
    def __init__(self):
        super().__init__()
    
    async def find_by_site_and_status(self, site_name: str, retry_status: str) -> List[ScraperFailedRecord]:
        """根据网站名称和重试状态查询失败记录"""
        return await self.find_by_filters(
            site_name=site_name,
            retry_status=retry_status,
            order_by=["-create_time"]
        )
    
    async def find_by_task_id(self, task_id: str) -> List[ScraperFailedRecord]:
        """根据任务ID查询失败记录"""
        return await self.find_by_filters(
            task_id=task_id,
            order_by=["-create_time"]
        )
    
    async def find_by_item_reference(self, site_name: str, item_reference: str) -> Optional[ScraperFailedRecord]:
        """根据数据项引用查询失败记录"""
        results = await self.find_by_filters(
            site_name=site_name,
            item_reference=item_reference,
            order_by=["-create_time"],
            limit=1
        )
        return results[0] if results else None
    
    async def update_retry_status(self, record_id: int, retry_status: str, 
                                 retry_count: Optional[int] = None,
                                 last_retry_time: Optional[datetime] = None,
                                 error_message: Optional[str] = None) -> bool:
        """更新重试状态"""
        update_data = {"retry_status": retry_status}
        
        if retry_count is not None:
            update_data["retry_count"] = retry_count
        
        if last_retry_time is not None:
            update_data["last_retry_time"] = last_retry_time
        
        if error_message is not None:
            update_data["error_message"] = error_message
        
        result = await self.update_by_pk(record_id, update_data)
        return result is not None
    
    async def find_pending_retries(self, site_name: str, max_retry_exceeded: bool = False) -> List[ScraperFailedRecord]:
        """查询待重试的记录"""
        return await self.find_by_filters(
            site_name=site_name,
            retry_status=RetryStatus.PENDING,
            order_by=["create_time"]
        )
